#!/usr/bin/env bash

# Default Python Versions
# shellcheck source=bin/default_pythons
source "bin/default_pythons"

testAirflow() {
  export SLUGIFY_USES_TEXT_UNIDECODE="yes"
  compile "airflow"
  assertCaptured "apache-airflow==1.10.2"
  assertCapturedSuccess
}

testPipenv() {
  compile "pipenv"
  assertCapturedSuccess
}

testPipenvLock() {
  compile "pipenv-lock"
  assertCapturedSuccess
}

testPipenvVersion() {
  compile "pipenv-version"
  assertCaptured $DEFAULT_PYTHON_VERSION
  assertCapturedSuccess
}

testPipenvVersion2() {
  compile "pipenv-version2"
  assertCaptured $LATEST_27
  assertCapturedSuccess
}
testPipenvFullVersion() {
  compile "pipenv-full-version"
  assertCaptured "3.6.3"
  assertCapturedSuccess
}

testNoRequirements() {
  compile "no-requirements"
  assertCapturedError
}

testCollectstatic() {
  compile "collectstatic"
  assertCaptured "collectstatic"
}

testGEOS() {
  export BUILD_WITH_GEO_LIBRARIES=1
  compile "geos"
  assertCaptured "geos"
  assertCapturedSuccess
}

testNLTK() {
  # NOTE: This is a RuntimeWarning emitted by Python 3's runpy.py script
  # which is what is used when you call `python -m <module>`. This is due to
  # how nltk imports things. It's not actually an error, but it would probably
  # be bad to silence in Production.
  export PYTHONWARNINGS="ignore::RuntimeWarning"
  compile "nltk"
  assertCaptured "[nltk_data] Downloading package city_database" "STD_ERR"
  assertCapturedSuccess
}

testSetupPy() {
  compile "setup-py"
  assertCaptured "maya"
  assertCapturedSuccess
}


testStandardRequirements() {
  compile "requirements-standard"
  assertCaptured "requests"
  assertCapturedSuccess
}

testPsycopg2() {
  compile "psycopg2"
  assertCaptured "psycopg2"
  assertCapturedSuccess
}

testCffi() {
  compile "cffi"
  assertCaptured "cffi"
  assertCapturedSuccess
}

testPylibmc() {
  compile "pylibmc"
  assertCaptured "pylibmc"
  assertCapturedSuccess
}

testPythonDefault() {
  updateVersion "pythonDefault" $DEFAULT_PYTHON_VERSION
  compile "pythonDefault"
  assertCaptured $DEFAULT_PYTHON_VERSION
  assertNotCaptured "security update"
  assertCapturedSuccess
}

testPython2() {
    updateVersion "python2" $LATEST_27
    echo $LATEST_27 > "runtime.txt"
    compile "python2"
    assertCaptured $LATEST_27
    assertNotCaptured "security update"
    assertCapturedSuccess
}

testPython2_warn() {
    compile "python2_warn"
    assertCaptured "python-2.7.15"
    assertCaptured "security update!"
    assertCapturedSuccess
}

testPython2_fail() {
    compile "python2_fail"
    assertCaptured "Aborting"
    assertCapturedError
}

testPython3_4() {
  if [[ $STACK != "cedar-14" ]]; then
    updateVersion "python3_4" $LATEST_34
    compile "python3_4"
    assertCaptured $LATEST_34
    assertNotCaptured "security update"
    assertCapturedSuccess
  fi
}

testPython3_4_warn() {
  compile "python3_4_warn"
  if [[ $STACK = "cedar-14" ]]; then
    assertCaptured "python-3.4.0"
    assertCaptured "security update!"
    assertCapturedSuccess
  else
    assertCapturedError
  fi
}

testPython3_4_fail() {
    compile "python3_4_fail"
    assertCaptured "Aborting"
    assertCapturedError
}

testPython3_5() {
  if [[ $STACK != "cedar-14" ]]; then
    updateVersion "python3_5" $LATEST_35
    compile "python3_5"
    assertCaptured $LATEST_35
    assertNotCaptured "security update"
    assertCapturedSuccess
  fi
}

testPython3_5_warn() {
  compile "python3_5_warn"
  if [[ $STACK = "cedar-14" ]]; then
    assertCaptured "python-3.5.3"
    assertCaptured "security update!"
    assertCapturedError
  else
    assertCapturedError
  fi
}

testPython3_5_fail() {
    compile "python3_5_fail"
    assertCaptured "Aborting"
    assertCapturedError
}

testPython3_6() {
  updateVersion "python3_6" $LATEST_36
  compile "python3_6"
  assertCaptured $LATEST_36
  assertNotCaptured "security update"
  assertCapturedSuccess
}

testPython3_6_warn() {
  compile "python3_6_warn"
  assertCaptured "python-3.6.7"
  assertCaptured "security update!"
  assertCapturedSuccess
}

testPython3_6_fail() {
    compile "python3_6_fail"
    assertCaptured "Aborting"
    assertCapturedError
}

testPython3_7() {
  updateVersion "python3_7" $LATEST_37
  compile "python3_7"
  if [[ $STACK = "cedar-14" ]]; then
    assertCapturedError
  else
    assertNotCaptured "security update"
    assertCaptured $LATEST_37
    assertCapturedSuccess
  fi
}

testPython3_7_warn() {
  compile "python3_7_warn"
  if [[ $STACK = "cedar-14" ]]; then
    assertCapturedError
  else
    assertCaptured "python-3.7.1"
    assertCaptured "security update!"
    assertCapturedSuccess
  fi
}

testPython3_7_fail() {
  compile "python3_7_fail"
  assertCaptured "Aborting"
  assertCapturedError
}

testGitEgg() {
  compile "git-egg"
  assertCaptured "requests"
  assertCapturedSuccess
}

testSmartRequirements() {
  local cache_dir="$(mktmpdir)"
  compile "requirements-standard" "$cache_dir"
  assertFile "requests" ".heroku/python/requirements-declared.txt"
  assertCapturedSuccess
  compile "psycopg2" "$cache_dir"
  assertCaptured "Uninstalling requests"
  assertFile "psycopg2" ".heroku/python/requirements-declared.txt"
  assertCapturedSuccess
}

testStackChange() {
  local cache_dir="$(mktmpdir)"
  mkdir -p "${cache_dir}/.heroku"
  echo "different-stack" > "${cache_dir}/.heroku/python-stack"
  compile "requirements-standard" "$cache_dir"
  assertCaptured "clearing cache"
  assertFile "$STACK" ".heroku/python-stack"
  assertCapturedSuccess
}


pushd $(dirname 0) >/dev/null
popd >/dev/null

source $(pwd)/test/utils

mktmpdir() {
  dir=$(mktemp -t testXXXXX)
  rm -rf $dir
  mkdir $dir
  echo $dir
}

detect() {
  capture $(pwd)/bin/detect $(pwd)/test/fixtures/$1
}

compile_dir=""

default_process_types_cleanup() {
  file="/tmp/default_process_types"
  if [ -f "$file" ]; then
    rm "$file"
  fi
}

compile() {
  default_process_types_cleanup
  bp_dir=$(mktmpdir)
  compile_dir=$(mktmpdir)
  cp -a $(pwd)/* ${bp_dir}
  cp -a ${bp_dir}/test/fixtures/$1/. ${compile_dir}
  capture ${bp_dir}/bin/compile ${compile_dir} ${2:-$(mktmpdir)} $3
}

compileDir() {
  default_process_types_cleanup

  local bp_dir=$(mktmpdir)
  local compile_dir=${1:-$(mktmpdir)}
  local cache_dir=${2:-$(mktmpdir)}
  local env_dir=$3

  cp -a $(pwd)/* ${bp_dir}
  capture ${bp_dir}/bin/compile ${compile_dir} ${cache_dir} ${env_dir}
}

release() {
  bp_dir=$(mktmpdir)
  cp -a $(pwd)/* ${bp_dir}
  capture ${bp_dir}/bin/release ${bp_dir}/test/fixtures/$1
}

assertFile() {
  assertEquals "$1" "$(cat ${compile_dir}/$2)"
}

source $(pwd)/test/shunit2
